package pishen;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import edu.uci.ics.jung.graph.Graph;

public class ThirdDiffusionSimulator {

	private Graph<Node, Edge> graph;
	private Map<Node, Double> infectedList;
	private List<Node> newestActiveList;
	private List<Node> newestActiveNeighborList;
	
	public ThirdDiffusionSimulator(Graph<Node, Edge> graph, List<Node> sourceList){
		this.graph = graph;
		this.infectedList = new HashMap<Node, Double>();
		for(Node node: sourceList){
			this.infectedList.put(node, 1.0);
		}
		this.newestActiveList = new ArrayList<Node>();
		this.newestActiveNeighborList = new ArrayList<Node>();
		for(Node node: infectedList.keySet()){
			this.newestActiveList.add(node);
		}
	}

	public void startSimulate(){
		int step = 0;
		while(newestActiveList.size() > 0){
			System.out.println("step=" + step + " node infected=" + infectedList.size());
			step++;
			for(Node node: graph.getVertices()){
				if(!infectedList.containsKey(node)){
					double weight = 0;
					double infectPower = 0;
					for(Node neighbor: graph.getSuccessors(node)){
						weight += 1;
						if(infectedList.containsKey(neighbor)){
							infectPower += infectedList.get(neighbor);
						}
					}
					if(Math.random() < (infectPower / weight)){
						newestActiveNeighborList.add(node);
					}
				}
			}
			newestActiveList.clear();
			for(Node node: infectedList.keySet()){
				infectedList.put(node, (infectedList.get(node) * 0.8));
			}
			for(Node node: newestActiveNeighborList){
				newestActiveList.add(node);
				infectedList.put(node, 1.0);
			}
			newestActiveNeighborList.clear();
		}
	}
	
	public List<Node> getInfectedList(){
		List<Node> list = new ArrayList<Node>();
		for (Node node: infectedList.keySet()){
			list.add(node);
		}
		return list;
	}
	
}
